#include "UtilityPCH.h"
#include "UT_BxDFBase.h"
#include "UT_MathHelper.h"

using namespace Utility;
//----------------------------------------------------------------------
// UT_BxDFBase
//----------------------------------------------------------------------
UT_BxDFBase::UT_BxDFBase(UT_BxDFBase::BxDFType eType)
	: m_eBxDFType(eType)
{
}
//----------------------------------------------------------------------
UT_BxDFBase::~UT_BxDFBase()
{

}
//----------------------------------------------------------------------
bool UT_BxDFBase::MatchesFlags(BxDFType eFlags) const
{
	 return (m_eBxDFType & eFlags) == m_eBxDFType;
}
//----------------------------------------------------------------------

//----------------------------------------------------------------------
// UT_BxDFReverse
//----------------------------------------------------------------------
UT_BxDFReverse::UT_BxDFReverse(UT_BxDFBase* b)
	: UT_BxDFBase(BxDFType(b->m_eBxDFType ^ (BSDF_REFLECTION | BSDF_TRANSMISSION)))
{
	m_pkBRDF = b;
}
//----------------------------------------------------------------------
UT_SpectrumUsed UT_BxDFReverse::f(const UT_Vec3Float& wo, const UT_Vec3Float& wi) const
{
	 return m_pkBRDF->f(wo, UT_MathHelper::ReverseHemiSphere(wi));
}
//----------------------------------------------------------------------
UT_SpectrumUsed UT_BxDFReverse::Sample_f(const UT_Vec3Float& wo, UT_Vec3Float* wi, float u1, float u2, float *pdf) const
{
	UT_SpectrumUsed f = m_pkBRDF->Sample_f(wo, wi, u1, u2, pdf);
	*wi = UT_MathHelper::ReverseHemiSphere(*wi);
	return f;
}
//----------------------------------------------------------------------
UT_SpectrumUsed UT_BxDFReverse::rho(const UT_Vec3Float& wo, int32_t nSamples, const float *samples) const
{
	return m_pkBRDF->rho(UT_MathHelper::ReverseHemiSphere(wo), nSamples, samples);
}
//----------------------------------------------------------------------
UT_SpectrumUsed UT_BxDFReverse::rho(int nSamples, const float *samples1, const float *samples2) const
{
	return m_pkBRDF->rho(nSamples,samples1,samples2);
}
//----------------------------------------------------------------------
//UT_BxDFScale
//----------------------------------------------------------------------
UT_BxDFScale::UT_BxDFScale(UT_BxDFBase* b, const UT_SpectrumUsed& sc)
	: UT_BxDFBase(b->m_eBxDFType)
	, m_pkBRDF(b)
	, m_kSpecutrumScale(sc)
{

}
//----------------------------------------------------------------------
UT_SpectrumUsed UT_BxDFScale::f(const UT_Vec3Float& wo, const UT_Vec3Float& wi) const
{
	return m_kSpecutrumScale * m_pkBRDF->f(wo, wi);
}
//----------------------------------------------------------------------
UT_SpectrumUsed UT_BxDFScale::Sample_f(const UT_Vec3Float& wo, UT_Vec3Float* wi, float u1, float u2, float *pdf) const
{
	UT_SpectrumUsed f = m_pkBRDF->Sample_f(wo, wi, u1, u2, pdf);
	return m_kSpecutrumScale * f;
}
//----------------------------------------------------------------------
UT_SpectrumUsed UT_BxDFScale::rho(const UT_Vec3Float& wo, int32_t nSamples, const float *samples) const
{
	return m_kSpecutrumScale * m_pkBRDF->rho(wo,nSamples,samples);
}
//----------------------------------------------------------------------
UT_SpectrumUsed UT_BxDFScale::rho(int nSamples, const float *samples1, const float *samples2) const
{
	return m_kSpecutrumScale * m_pkBRDF->rho(nSamples,samples1,samples2);
}
//----------------------------------------------------------------------